#pragma once

#include "Misc/EngineEditorMacros.h"
#include "Object/Object.h"
#include "Window/EditorContextMenuModel.h"
#include "MaterialGraphNodeView.m.h"

class RMaterialGraphNodeViewModel;
class RWidget;
class RMaterialGraphPinView;
class RMaterialGraphView;

RCLASS()
class RMaterialGraphNodeView : public RObject
{
    ROBJECT

public:
    virtual void BindViewModel(TSharedObjectPtr<RMaterialGraphNodeViewModel> InModel);
    void CreateWidget(TSharedObjectPtr<RWidget> InParentWidget);

    //create lines widget except title
    //those lines will be deleted when view model require regenerate
    //it's parent widget is the root widget
    virtual void RegenerateContentWidget() {};

    void FillContextMenu(TVector<SEditorContextMenuLine>& InOutMenuLines);
protected:
    TSharedObjectPtr<RMaterialGraphView> GetGraphView();
    


    TWeakObjectPtr<RMaterialGraphNodeViewModel> BaseViewModel;

    TVector<TSharedObjectPtr<RMaterialGraphPinView>> InputPinViews;
    TVector<TSharedObjectPtr<RMaterialGraphPinView>> OutputPinViews;

    TSharedObjectPtr<RWidget> RootWidget;

    TSharedObjectPtr<RWidget> CreateNodeWidget(TSharedObjectPtr<RWidget> InParentWidget);
    

    /// @brief create a output pin widget, just have a name and a pin
    /// @param InNodeWidget 
    /// @param InOutputPinIndex 
    /// @param InLineIndex  the line index in node, base 0
    /// @return 
    TSharedObjectPtr<RWidget> CreateSimpleOutputPinWidget(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InOutputPinIndex
        ,int64_t InLineIndex
        );

    TSharedObjectPtr<RWidget> CreateSimpleInputPinWidget(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InOutputPinIndex
        ,int64_t InLineIndex
        );

    TSharedObjectPtr<RWidget> CreateLine(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InLineIndex
        ,int64_t InLineNum=1
        );



    /// @brief create a input pin with value type of float
    ///  without value limit, can set any float value
    /// @param InNodeWidget 
    /// @param InParentWidget
    /// @param InInputPinIndex 
    /// @param InLineIndex 
    /// @return 
    TSharedObjectPtr<RWidget> CreateVector1DInputPinWidgetWithoutLimit(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InInputPinIndex
        ,int64_t InLineIndex
        );

    TSharedObjectPtr<RWidget> CreateVector1DInputPinWidgetWithLimit(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InInputPinIndex
        ,int64_t InLineIndex
        ,float InMinValue = 0.0f
        ,float InMaxValue = 1.0f
        );

    //create a float value edit widget
    TSharedObjectPtr<RWidget> CreateVector1DWidgetWithoutLimit(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InLineIndex
        ,TDelegate<float> InGetValue
        ,TDelegate<void,float> InOnValueChanged
    );
    
    TSharedObjectPtr<RWidget> CreateVector2DInputPinWidget(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InInputPinIndex
        ,int64_t InLineIndex
    );    

    TSharedObjectPtr<RWidget> CreateVector3DInputPinWidget(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InInputPinIndex
        ,int64_t InLineIndex
    );

    //create a color input pin widget
    //will use all 4 channels
    TSharedObjectPtr<RWidget> CreateColorInputPinWidget(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InInputPinIndex
        ,int64_t InLineIndex
    ); 


    TSharedObjectPtr<RWidget> CreateCheckBoxWidget(
        TSharedObjectPtr<RWidget> InNodeWidget
        ,TSharedObjectPtr<RWidget> InParentWidget
        ,int64_t InLineIndex
        ,TDelegate<bool> InCheckState
        ,TWidgetAttribute<CString> InText
        ,TDelegate<void,bool> InOnCheckStatedChanged
    );
};